#include <pmemory.h>

char* img_file;
//="/home/zhoupu/ysyx-workbench/am-kernels/tests/cpu-tests/build/dummy-riscv64-npc.bin";
static const uint32_t default_img[] = {
    0x06400293,
    0xFFF28313,
    0x00230393,
    0x00130393,
    0x00130393,
    0x00000073};
unsigned long img_size = 0;

void init_mem();
void init_sdb();
void init_cpu();
void sdb_set_batch_mode();
void init_difftest(const char *ref_so_file, long img_size);
void init_device();


long load_img() {
  if (img_file == NULL) {
    memcpy(vaddr_to_paddr(PMEM_BASE), default_img, sizeof(default_img));
    return sizeof(default_img) / sizeof(char); // built-in image size
  }
  FILE *fp = fopen(img_file, "rb");
  assert(fp);

  fseek(fp, 0, SEEK_END);
  long size = ftell(fp);

  fseek(fp, 0, SEEK_SET);
  int ret = fread(vaddr_to_paddr(PMEM_BASE), size, 1, fp);
  assert(ret == 1);

  fclose(fp);
  img_size = size;
  return size;
}

void parse_args(int argc, char *argv[]) {
  const struct option table[] = {
      {"batch", no_argument, NULL, 'b'},
      {0, no_argument, NULL, 0}
  };
  int o = 0;
  while (-1 != (o = getopt_long(argc, argv, "-b", table, NULL))) {
    switch (o) {
      case 'b': sdb_set_batch_mode(); break;
      case 1: img_file = optarg; return;
      default: break;
    }
  }
  return;
}

void init_monitor(int argc, char *argv[]) {

  parse_args(argc, argv);

  init_mem();

  init_cpu();

  printf("load image from: %s\n", img_file == NULL? "default img" : img_file);

  img_size = load_img();

  init_device();

  // init_difftest("/home/zhoupu/ysyx-workbench/nemu/build/riscv64-nemu-interpreter-so", img_size);

  init_sdb();
}
